package com.fh.service.loantaskimpl;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.druid.util.StringUtils;
import com.fh.mapper.loan.CallLoanBorrowDetailMapper;
import com.fh.mapper.loan.CallLoanBorrowInfoMapper;
import com.fh.mapper.loan.CallLoanInfoMapper;
import com.fh.mapper.loan.CallLoanOverInfoMapper;
import com.fh.mapper.loan.CallLoanSysLogMapper;
import com.fh.mapper.loan.RepayRecordMapper;
import com.fh.mapper.loan.SysUserMapper;
import com.fh.model.Page;
import com.fh.model.loan.CallLoanBorrowDetail;
import com.fh.model.loan.CallLoanBorrowInfo;
import com.fh.model.loan.CallLoanInfo;
import com.fh.model.loan.CallLoanInfoDto;
import com.fh.model.loan.CallLoanOverInfo;
import com.fh.model.loan.CallLoanSysLog;
import com.fh.model.loan.RepayRecord;
import com.fh.model.loan.SysUser;
import com.fh.service.cuijimanage.CuijimanageServiceImpl;
import com.fh.util.Const;
import com.fh.util.DateUtil;
import com.fh.util.PageData;

import tk.mybatis.mapper.util.StringUtil;

/**
 * 结案
 */
@Service
public class LoanTaskOverServiceImpl {
    private Logger logger = LoggerFactory.getLogger(LoanTaskOverServiceImpl.class);

    @Autowired
    private CallLoanInfoMapper callLoanInfoMapper;
    @Autowired
    private CallLoanSysLogMapper callLoanSysLogMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private CuijimanageServiceImpl cuijimanageServiceImpl;
    
    @Autowired
    private RepayRecordMapper repayRecordMapper;
    @Autowired
    private CallLoanBorrowInfoMapper callLoanBorrowInfoMapper;
    @Autowired
    private CallLoanBorrowDetailMapper callLoanBorrowDetailMapper;
    
    @Autowired
	private CallLoanOverInfoMapper callLoanOverInfoMapper;
    
    public List<PageData> callTaskOverList(Page page) {
    	List<PageData> list = callLoanOverInfoMapper.findTaskOverListPage(page);
    	//addOverTime(list);
        return list;
    }
    /**
     * 计算实际的结案时间
     * @param list
     */
    private void addOverTime(List<PageData> list){
    	list.stream()
    	.forEach(x->{
    		Object endDate = x.get("end_case_date");
    		 
    		String endDateStr = endDate != null ? endDate.toString() : "";
    		DateFormat fromat = new SimpleDateFormat("yyyy-MM-dd");
    		Date date = null;
    		try {
    			if(!StringUtils.isEmpty(endDateStr)){
				 date = fromat.parse(endDateStr);
				 Date oldOverTime = fromat.parse("2017-09-13");
				 Calendar cal = Calendar.getInstance();
				 if(date.getTime() >= oldOverTime.getTime()){//今日现金二期上线之后实际结案时间比今日现金跑批时间少一天
					 cal.setTime(date);
					 cal.add(Calendar.DAY_OF_MONTH, -1);
					 date = cal.getTime();
				 }
    			}
			} catch (ParseException e) {
				logger.error("日期异常  endDateStr {}" , e.getMessage());
			}
    		if(date != null){
    			x.put("overTime", date);
    		}
    	
    	});
    	
    }
    
    public Map<String, Object> callLoanOverExl(HttpServletResponse response, Page page) {
    	
        Map<String, Object> map = new HashMap<String,Object>();
		List<String> titles = new ArrayList<String>();
		
		titles.add("催收编号"); 	//1
		titles.add("借款人姓名");  		//2
		titles.add("借款产品名称");			//3
		titles.add("逾期期数");			//4
		titles.add("累计还款");  		//5
		titles.add("逾期阶段");	//6
		titles.add("逾期天数");	//7
		titles.add("催收员");	//8
		titles.add("罚息金额");	//9
		titles.add("入案时间");	//10
		titles.add("分派时间");	//11
		titles.add("结案时间");	//12
		titles.add("实际结案时间");//13
		titles.add("催收状态");//14
		titles.add("还款订单号");//15
		map.put("titles", titles);
        
        try {
            List<PageData> userList = callLoanOverInfoMapper.callLoanOverExl(page); 
            
            List<PageData> infolist = new ArrayList<PageData>();
            for (int i = 0; i < userList.size(); i++) {
            	PageData vpd = new PageData();
            	vpd.put("var1", userList.get(i).get("call_loan_nid")== null ? " " : userList.get(i).get("call_loan_nid").toString());     //1
            	vpd.put("var2", userList.get(i).get("real_name")== null ? " " : userList.get(i).get("real_name").toString());   //2
            	vpd.put("var3", userList.get(i).get("product_name")== null ? " " : userList.get(i).get("product_name").toString());    //3
            	vpd.put("var4", userList.get(i).get("period").toString());    //4
            	vpd.put("var5", userList.get(i).get("actual_recover_amount_count")== null ? "0.00" : userList.get(i).get("actual_recover_amount_count").toString());    //5
            	vpd.put("var6", userList.get(i).get("overdue_duration") == null ? " " : userList.get(i).get("overdue_duration").toString());    //6
            	vpd.put("var7", userList.get(i).get("overdue_date") == null ? " " : userList.get(i).get("overdue_date").toString());    //7
            	vpd.put("var8", userList.get(i).get("userName") == null ? " " : userList.get(i).get("userName").toString());    //8
            	vpd.put("var9", userList.get(i).get("overdue_fee").toString());    //8
            	vpd.put("var10", userList.get(i).get("create_time") == null ? " " : userList.get(i).get("create_time").toString().substring(0, 19));    //9
            	vpd.put("var11", userList.get(i).get("call_time") == null ? " " : userList.get(i).get("call_time").toString().substring(0, 19));    //11
            	vpd.put("var12", userList.get(i).get("end_case_date") == null ? " " : userList.get(i).get("end_case_date").toString().substring(0, 19));    //10
            	vpd.put("var13", userList.get(i).get("actual_end_case_date") == null ? " " : userList.get(i).get("actual_end_case_date").toString().substring(0, 19));    //10
            	vpd.put("var14", "已结案");    //14
            	vpd.put("var15", userList.get(i).get("repayment_id").toString());    //15
				
                infolist.add(vpd);
            }
            map.put("varList", infolist);
        } catch (Exception e) {
            logger.error("导出信息异常====> {}", e);
        }
        return map;
    }

    /**
     * 结案
     *
     * @param repaymentId
     * @param notReturnAmount
     * @return
     */
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
    public int updateByRepIdPaopi(String repaymentId, BigDecimal notReturnAmount,Integer sourceType) {
        //查询案件是否存在并且没有结案
        CallLoanInfoDto callLoanInfoDto = new CallLoanInfoDto();
        callLoanInfoDto.setRepaymentId(repaymentId);
        int status = -1;
        int result = -2;
        try {
        	CallLoanInfoDto callLoanInfo = callLoanInfoMapper.fetchByRepaymentId(callLoanInfoDto);
        	 if (callLoanInfo != null) {
                 //添加催计消息
                 CallLoanSysLog callLoanSysLog = new CallLoanSysLog();
                 callLoanSysLog.setTitle("已结案消息通知");
                 callLoanSysLog.setContent("催收编号" + callLoanInfo.getCallLoanNid() + "已结案，请查看");
                 callLoanSysLog.setStatus(0);
                 callLoanSysLog.setIsDelete(0);
                 callLoanSysLog.setCreateTime(new Date());
                 callLoanSysLog.setUpdateTime(new Date());
                 callLoanSysLog.setCallUser(callLoanInfo.getCallUser());
                 callLoanSysLogMapper.insertCuijiMsg(callLoanSysLog);
                 //添加催计消息
                 if (callLoanInfo.getStatus() != 3 && callLoanInfo.getStatus() != 5) {//判断案件状态不是委外的案件
                     //该案件不是委外催收中案件
                     status = Const.CONSTANT_STRUTS2;
                 } else {
                     //该案件为委外催收中案件
                     status = Const.CONSTANT_STRUTS4;
                 }
                 if(callLoanInfo.getStatus() != 2 && callLoanInfo.getStatus() != 4){//如果结案，则不进行修改案件状态
                	 
                	 String date=this.actualOverTime(sourceType);
                	 
                 	result=this.updateByEndCase(repaymentId, notReturnAmount, status, callLoanInfo.getVersion(),date);//返回结案成功
                 }else{
                 	result=Const.OVER_CASH;//返回已经是结案
                 }
             }else{
             	result=Const.NOT_RETURN_MSG;//返回不存在该还款信息
             }
		} catch (Exception e) {
			logger.error("callLoanInfo查询异常" , e.getMessage());
			result=Const.THOERS_ERROR;//出现其他异常
		}
        return result;
    }

    /**
     * 逾期结案处理
     *
     * @param repaymentId
     * @param notReturnAmount
     * @param status
     * @param version
     * @return
     */
    public int updateByEndCase(String repaymentId, BigDecimal notReturnAmount, int status, Integer version ,String daTe) {
        CallLoanInfo info = new CallLoanInfo();
        info.setRepaymentId(repaymentId);
        info.setNotReturnAmount(notReturnAmount);
        info.setStatus(status);
        info.setVersion(version);
        Date actualEndCaseDate=DateUtil.fomatDate(daTe);
		info.setActualEndCaseDate(actualEndCaseDate);
        int a = callLoanInfoMapper.updateByRepIdPaopi(info);
        if (a <= 0) {
            throw new RuntimeException("乐观锁失败!");
        }
        return a;
    }

    public List<PageData> overAmountOrdList(Page page) {
        return callLoanInfoMapper.overAmountOrdListPage(page);
    }

    /**
     * map 循环去空
     *
     * @param pd 传入参数Map
     */
    public PageData setPdWithTrim(PageData pd) {
        //循环去空
        Iterator it = pd.entrySet().iterator();
        Map.Entry entry;
        while (it.hasNext()) {
            entry = (Map.Entry) it.next();
            Object valueObj = entry.getValue();
            pd.put((String) entry.getKey(), null == valueObj ? "" : valueObj.toString().trim());
        }
        return pd;
    }

    public SysUser findUserByUserName(Map<String, Object> map) {
        return sysUserMapper.findUserByUserName(map);
    }

    /**
     * 判断实际结案时间的时间节点
     * @return
     */
    public String actualOverTime(Integer sourceType){
    	Date da=new Date();
    	String dt2=null;
    	
		//DateFormat df1 = new SimpleDateFormat("HH");//当前时间
		DateFormat df2 = new SimpleDateFormat("yyyy-MM-dd");//实际结案时间
		//String ss=df1.format(da);
		//Integer ii=Integer.valueOf(ss);//获取当前时间并转化成整数进行判断
		//int limitNum=9;
		
		if(1==sourceType){//来源今日现金跑批，今日现金跑批的结案实际结案时间比结案时间少于一天
			Calendar c = Calendar.getInstance();
			c.setTime(da);
			c.add(Calendar.DATE, - 1);
			dt2 = df2.format(c.getTime());
		}else{//实时还款的结案时间就是当前时间
			dt2=df2.format(new Date());
		}
    	return dt2;
    }
    /**
     * MQ结案数据
     */
    public void getOverCashMsg(String msg){
    	
    	com.alibaba.fastjson.JSONObject jsonMsg=com.alibaba.fastjson.JSONObject.parseObject(msg);
    	
    	String repaymentId=jsonMsg.getString("repaymentId");//获取还款订单号
    	
    	
    	Map<String,Object> map = new HashMap<String,Object>();
    	map=jsonMsg.getJSONObject("data");
    	BigDecimal notReturnAmount=(BigDecimal) map.get("acountYet");//已还金额
    	Integer sourceType=(Integer) map.get("sourceType");//1 跑批 2 实时
    	Integer repayType=(Integer) map.get("repayType");//1 为全部还清 0为部分还款
    	logger.info("·········MQ信息结案数据已还金额="+notReturnAmount+"·········还款方式="+repayType);
    	if(1==repayType){
    		int a = this.updateByRepIdPaopi(repaymentId,notReturnAmount,sourceType);
    		if(1==a){
    			logger.info("··············MQ结案数据结案成功====》》repaymentId···············="+repaymentId);
    			
    			logger.info("-------------结案数据转移开始-------------");
    	    	selectCaseOver(repaymentId);
    	    	logger.info("-------------结案数据转移结束-------------");
    		}else if(a==Const.OVER_CASH){
    			logger.info("·············已经做过结案操作====》》repaymentId··················="+repaymentId);
	  	    }else if(a==Const.NOT_RETURN_MSG){
	  	    	logger.info("·············不存在该逾期案件====》》repaymentId··················="+repaymentId);
	  	    }else if(a==Const.THOERS_ERROR){
	  	    	logger.info("·············其他异常,结案失败====》》repaymentId·················="+repaymentId);
	  	    }else{
	  	    	logger.info("·············未知异常,结案失败====》》repaymentId·················="+repaymentId);
	  	    }
	    }
    	
    }
    
    /**
     * 对repay_record_log表记录两个系统对接跑批时产生的遗漏数据进行补漏处理
     * @return
     */
    public List<RepayRecord> findRepayRecordLessOverList(){
    	return repayRecordMapper.findRepayRecordLessOverList();
    }
    
    /**
     * 对repay_record_log表记录两个系统对接跑批时产生的遗漏数据进行补漏处理 补漏定时job
     * @author dell、
     *
     */
    public int overCaseJobExecute(){
    	//查询所有的遗漏的案件
    	List<RepayRecord> repayRecords=this.findRepayRecordLessOverList();
    	int a=-1;
		if(repayRecords!=null){
			for(int i=0;i<repayRecords.size();i++){
				CallLoanInfo info = new CallLoanInfo();
				String repaymentId=repayRecords.get(i).getRepaymentId();//还款订单号
				BigDecimal notReturnAmount=repayRecords.get(i).getAcountYet();//已还金额
				//*****************************************
				BigDecimal capitalRemain=repayRecords.get(i).getCapitalRemain();//未还本金
				BigDecimal interestRemain=repayRecords.get(i).getInterestRemain();//未还利息
				BigDecimal userReduOverdueFee=repayRecords.get(i).getUserReduOverdueFee();//已使用的罚息减免
				//*****************************************
				Integer repayType=repayRecords.get(i).getRepayType();//还款类型1结清 0 部分还款
				Integer sourceType=2;//跑漏数据为实时结案，1 跑批 2 实时
				//======================================================
				Map<String,Object> map2 = new HashMap<>();
				map2.put("repaymentId", repaymentId);
				//催收人借贷情况表
				CallLoanBorrowInfo borrowInfo = callLoanBorrowInfoMapper.selectLoanBorrowInfo(map2);
				//催收人还款详情表
				//查询主表信息
				CallLoanInfo callLoanInfo = callLoanInfoMapper.selectByRepaymentId(repaymentId);
				CallLoanBorrowDetail borrowDetail = callLoanBorrowDetailMapper.selectReturnDetail(String.valueOf(callLoanInfo.getUserId()), repaymentId);
				info.setReceveFee(borrowDetail.getReceveOverdueFee());//设置已还罚息金额
				info.setRepaymentId(repaymentId);//还款订单号
				info.setActualRecoverAmount(notReturnAmount);//设置主表已还金额 =已还金额 
        		info.setOverdueCaptial(capitalRemain);//设置逾期本金 = 未还本金
        		info.setOverdueInterest(interestRemain);//设置逾期利息 = 未还利息
        		info.setUserReduOverdueFee(userReduOverdueFee);//设置已使用罚息减免金额
        		if (callLoanInfo != null) {
        			info.setVersion(callLoanInfo.getVersion());//版本号
        		}
				if(1==repayType){//判断全部结清 
					logger.info("跑漏结案数据***********");
					a=this.updateByRepIdPaopi(repaymentId, notReturnAmount, sourceType);
					if (borrowInfo != null) {
						//如果详情表有数据就更新
						this.updateByRepayRecordLog(info, borrowInfo);
					}
					if(1==a){
						logger.info("··············跑漏数据····MQ结案数据结案成功====》》repaymentId···············="+repaymentId);
						repayRecordMapper.updateIsMissStatus(repaymentId);//修改repay_record_log表中的is_miss为N
					}else if(a==Const.OVER_CASH){
						logger.info("··············跑漏数据····已经做过结案操作====》》repaymentId··················="+repaymentId);
						repayRecordMapper.updateIsMissStatus(repaymentId);//修改repay_record_log表中的is_miss为N
					}else if(a==Const.NOT_RETURN_MSG){
						logger.info("··············跑漏数据····不存在该逾期案件====》》repaymentId··················="+repaymentId);
						repayRecordMapper.updateIsMissStatus(repaymentId);//修改repay_record_log表中的is_miss为N
					}else if(a==Const.THOERS_ERROR){
						logger.info("··············跑漏数据····其他异常,结案失败====》》repaymentId·················="+repaymentId);
					}else{
						logger.info("··············跑漏数据····未知异常,结案失败====》》repaymentId·················="+repaymentId);
					}
				}else{
					if (borrowInfo != null) {
						//如果详情表有数据就更新
						this.updateByRepayRecordLog(info, borrowInfo);
						repayRecordMapper.updateIsMissStatus(repaymentId);//修改repay_record_log表中的is_miss为N
					}
					
				}
			}
		}
		return a;
    }
    /**
     * 补漏
     * @param info
     * @return
     */
    public int updateByRepayRecordLog(CallLoanInfo info,CallLoanBorrowInfo borrowInfo) {
    	if (borrowInfo != null) {
			info.setNotReturnAmount(borrowInfo.getAcountRemain());//设置主表未还金额
			info.setOverdueAmount(borrowInfo.getAcountRemain());//设置逾期总金额 = 未还金额
			info.setOverdueManFee(borrowInfo.getRemainBorrowFee());//设置逾期管理费 = 未还管理费
			info.setOverdueSerFee(borrowInfo.getRemainServiceFee());//设置逾期平台服务费 = 未还平台服务费 
			info.setOverdueFee(borrowInfo.getRemainOverdueFee());//设置未还罚息
			info.setRemainAccount(info.getOverdueAmount().subtract(info.getOverdueFee()));//累计未还金额 = 未还金额 - 未还罚息
		}
    	return callLoanInfoMapper.updateByMoney(info);
	}
    /**
     * 结案案件信息转移到结案表
     * @param repaymentId
     */
    public void selectCaseOver(String repaymentId){
    	CallLoanOverInfo callLoanOverInfo = callLoanOverInfoMapper.selectCaseOverByRepaymentId(repaymentId);
    	if(callLoanOverInfo!=null){//判断是否结案中存在改结案案子
    		logger.info("--------------结案数据转移-------结案数据表已存在该结案信息-----------------repaymentId=="+repaymentId);
    	}else{
    		CallLoanInfo callLoanInfo=callLoanInfoMapper.selectCaseOverByRepaymentId(repaymentId);//获取结案信息
    		logger.info("--------------结案数据转移-------转移的案件信息-----------------repaymentId=="+callLoanInfo.getRepaymentId());
			if(callLoanInfo != null){
				callLoanOverInfo=new CallLoanOverInfo();
				callLoanOverInfo.setRepaymentId(callLoanInfo.getRepaymentId());//还款订单号
				callLoanOverInfo.setCallLoanNid(callLoanInfo.getCallLoanNid());//催收编号
				callLoanOverInfo.setUserId(callLoanInfo.getUserId());//借款人ID
				callLoanOverInfo.setRealName(callLoanInfo.getRealName());//借款人姓名
				callLoanOverInfo.setContIdCard(callLoanInfo.getContIdCard());//借款人身份证
				callLoanOverInfo.setProductName(callLoanInfo.getProductName());//产品来源
				callLoanOverInfo.setBorrowNid(callLoanInfo.getBorrowNid());//借款编号
				callLoanOverInfo.setBorrowName(callLoanInfo.getBorrowName());//借款产品名称
				callLoanOverInfo.setPeriod(callLoanInfo.getPeriod());//逾期期数
				callLoanOverInfo.setPeriodTotal(callLoanInfo.getPeriodTotal());//逾期总期数
				callLoanOverInfo.setOverdueAmount(callLoanInfo.getOverdueAmount());//逾期总金额
				callLoanOverInfo.setOverdueInterest(callLoanInfo.getOverdueInterest());//逾期利息
				callLoanOverInfo.setOverdueCaptial(callLoanInfo.getOverdueCaptial());//逾期本金
				callLoanOverInfo.setOverdueManFee(callLoanInfo.getOverdueManFee());//逾期管理费
				callLoanOverInfo.setOverdueSerFee(callLoanInfo.getOverdueSerFee());//逾期服务费
				callLoanOverInfo.setOverdueFee(callLoanInfo.getOverdueFee());//未还罚息
				callLoanOverInfo.setRemainAccount(callLoanInfo.getRemainAccount());//待还金额
				callLoanOverInfo.setRecoverTime(callLoanInfo.getRecoverTime());//应还款时间
				callLoanOverInfo.setOverdueDate(callLoanInfo.getOverdueDate());//逾期天数
				callLoanOverInfo.setOverdueDuration(callLoanInfo.getOverdueDuration());//催收组
				callLoanOverInfo.setStatus(callLoanInfo.getStatus());//状态
				callLoanOverInfo.setIsCall(1);//是否分派
				callLoanOverInfo.setCallUser(callLoanInfo.getCallUser());//催收员ID
				callLoanOverInfo.setCallTime(callLoanInfo.getCallTime());//分派时间
				callLoanOverInfo.setCallType(callLoanInfo.getCallType());//催收方式
				callLoanOverInfo.setCallMark(1);
				callLoanOverInfo.setCreateTime(callLoanInfo.getCreateTime());//入案时间
				callLoanOverInfo.setBorrowDurationType(callLoanInfo.getBorrowDurationType());//借款期限类型
				callLoanOverInfo.setOverdueStage(callLoanInfo.getOverdueStage());//逾期阶段
				callLoanOverInfo.setEndCaseDate(callLoanInfo.getEndCaseDate());//结案时间
				callLoanOverInfo.setActualEndCaseDate(callLoanInfo.getActualEndCaseDate());//实际结案时间
				callLoanOverInfo.setNotReturnAmount(callLoanInfo.getNotReturnAmount());//未还金额
				callLoanOverInfo.setTelephone(callLoanInfo.getTelephone());//
				callLoanOverInfo.setAssignTime(callLoanInfo.getAssignTime());//委外时间
				callLoanOverInfo.setAssignCompany(callLoanInfo.getAssignCompany());//委外公司
				callLoanOverInfo.setBatchNumber(callLoanInfo.getBatchNumber());//批次号
				callLoanOverInfo.setAccountId(callLoanInfo.getAccountId());
				callLoanOverInfo.setProductSource(callLoanInfo.getProductSource());//产品来源
				callLoanOverInfo.setActualRecoverAmount(callLoanInfo.getActualRecoverAmount());//已还金额
				callLoanOverInfo.setCallResult(callLoanInfo.getCallResult());//催收结果
				callLoanOverInfo.setLastCallTime(callLoanInfo.getLastCallTime());//最后催收时间
				callLoanOverInfo.setPromiseRepaymentDay(callLoanInfo.getPromiseRepaymentDay());//承诺还款时间
				callLoanOverInfo.setReceveServiceFee(callLoanInfo.getReceveServiceFee());//已还平台服务费
				callLoanOverInfo.setUserReduOverdueFee(callLoanInfo.getUserReduOverdueFee());//已还平台服务费
				callLoanOverInfo.setCompensatoryStatus(callLoanInfo.getCompensatoryStatus());//代偿状态
				callLoanOverInfo.setUpdateTime(new Date());
				callLoanOverInfo.setProvince(callLoanInfo.getProvince());//客户户籍
				try {
					int i=callLoanOverInfoMapper.caseOverInsert(callLoanOverInfo);
					if(i==1){
						logger.info("--------------结案数据转移结案数据库成功-------------------");
					}
				} catch (Exception e) {
					logger.info("--------------结案数据转移结案数据库失败-------------------");
				}
			}
    	}
    }
}
